import {ElMessage} from 'element-plus'

const fs = require('fs')
import {movieDB} from './lowdb.ts'
import {videoImagesDir, videoRootDir} from '@/utils/config.ts'
import {DreamVideo, Movie} from '@/data/Dream'
import {setVideoOtherInfo} from '@/data/video.ts'
import {arraysHaveSameElements} from '@/utils/utils.ts'


function getDreamVideoDB(movie: Movie) {
    const dreamVideosDirName = `${movie.year}.${movie.name}`
    const star = movie.star ? `${movie.star}/` : ''
    const dreamVideosRootDir = `${videoRootDir}/${star}${dreamVideosDirName}/`
    const dreamVideos = movie.dreamVideos
    return {dreamVideosDirName, dreamVideosRootDir, dreamVideos}
}

function getVideoImagesMap(dreamVideosDirName: string) {
    // console.log(dreamVideosDirName)
    const videoImages = fs.readdirSync(videoImagesDir)
    const videoImagesMap = new Map<string, string[]>()

    for (let videoImage of videoImages) {
        if (!videoImage.startsWith(dreamVideosDirName)) continue
        const index = videoImage.lastIndexOf('_')
        const key = videoImage.substring(0, index)
        if (videoImagesMap.has(key)) {
            videoImagesMap.get(key).push(videoImage)
        } else {
            videoImagesMap.set(key, [videoImage])
        }
    }
    return videoImagesMap
}

function createNewDreamVideo(videoFileName: string, dreamVideosDirName: string) {
    const newDreamVideo: DreamVideo = {
        name: '',
        video: '',
        images: [],
        duration: 0,
        durationF: '',
        size: 0,
        sizeF: '',
    }
    // -01.33.32.763-01.34.56.669
    let videoName = videoFileName.replace(/(-(\d{2}\.){3}\d{3}){2}/, '')
    // 去除文件名后缀
    videoName = videoName.replace(/\.[^/.]{1,4}$/, '')
    // “年.电影名” 中间的点会被识别成任意字符
    dreamVideosDirName = dreamVideosDirName.replace('.', '\\.')
    // 去除文件名开头的“年.电影名.”
    // '//' 中间不能写变量，得使用RegExp
    videoName = videoName.replace(new RegExp('^'+dreamVideosDirName + '[\\.\\-,_]*'), '')
    newDreamVideo.name = videoName
    newDreamVideo.video = videoFileName
    return newDreamVideo
}

async function getNewDreamVideos(dreamVideosRootDir: string, dreamVideosDirName: string,
                           dreamVideos: DreamVideo[], videoImagesMap: Map<string, string[]>)
{
    let newDreamVideo : DreamVideo = <DreamVideo>{}
    const newDreamVideos: DreamVideo[] = []

    const dreamVideoFiles = fs.readdirSync(dreamVideosRootDir)
    dreamVideoFiles.sort()
    console.log('dreamVideoFiles', dreamVideoFiles)
    for (let videoFileName of dreamVideoFiles) {

        const dreamVideo = dreamVideos.find(v => v.video === videoFileName)
        const images = videoImagesMap.get(videoFileName)
        if (dreamVideo) {
            // 数据库里存在
            if (!images ||  // 没有图片文件
                arraysHaveSameElements(images, [...dreamVideo.images])    // 图片文件和数据库里存的是一样的
            ) {
                // 没有图片或者图片已经完全添加到数据库
                newDreamVideos.push(dreamVideo)
                continue
            } else {
                newDreamVideo = dreamVideo
            }
        } else {
            // 数据库里不存在
            newDreamVideo = createNewDreamVideo(videoFileName, dreamVideosDirName)
            await setVideoOtherInfo(newDreamVideo, dreamVideosRootDir, videoFileName)
        }
        if (images) {
            images.forEach((img) => {
                if (!newDreamVideo.images.includes(img)) {
                    ElMessage({message: img, type: 'success', duration: 8000})
                }
            })
            newDreamVideo.images = images
        }
        newDreamVideos.push(newDreamVideo)
    }
    return newDreamVideos
}


export async function loadVideos(name: string, year: number) {
    // 1、读取数据库存的数据
    // 不加 read 读取到的不是数据库里最新的数据，导致修改了封面，再加载时会把修改的封面还原
    const movie: Movie = movieDB.read()
        .find({name, year})
        .value()
    const {dreamVideosDirName, dreamVideosRootDir, dreamVideos} = getDreamVideoDB(movie)
    console.log('dreamVideos', dreamVideos)

    // 2、图片文件
    const videoImagesMap = getVideoImagesMap(dreamVideosDirName)
    console.log('videoImagesMap', videoImagesMap)

    // 3、视频文件
    const newDreamVideos = await getNewDreamVideos(dreamVideosRootDir, dreamVideosDirName, dreamVideos, videoImagesMap)
    console.log('newDreamVideos', newDreamVideos)

    // 有新的视频文件时，上面会更新了电影的总视频信息，movieLowDB拿不到数据库最新的数据，所以需要重新查询电影
    movieDB.find({name, year})
        .set('dreamVideos', newDreamVideos)
        .write()
}

async function doLoadMovies(videoDir: string, star: string) {
    const files = fs.readdirSync(videoDir)
    files.sort()
    for (let fileName of files) {
        const strings = fileName.split('.')
        if (strings.length === 2) {
            // 是电影文件件
            const year = parseInt(strings[0])
            const name = strings[1]
            const movies = movieDB.read()
            let movie: Movie = movies.find({name, year}).value()
            if (!movie) {
                // 新增这部电影数据
                movie = {
                    name: name,
                    year: year,
                    star: star,
                    images: ['', ''],
                    dreamVideos: [],
                    duration: 0,
                    durationF: '',
                    size: 0,
                    sizeF: '',
                }
                movies.push(movie)
                    .write()
                await loadVideos(name, year)
            }
        } else {
            // 是明星文件夹
            if (videoDir === videoRootDir) {    // 只进一层递归
                // 电影文件夹在明星文件里面
                await doLoadMovies(`${videoDir}/${fileName}`, fileName)
            }
        }
    }
}

export async function loadMovies() {
    await doLoadMovies(videoRootDir, '')
}
